
#include "includes.h"

#define MAX_BRIGHTNESS 255

uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length;    //data length
uint32_t aun_red_buffer[500];    //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid;   //indicator to show if the SP02 calculation is valid
int32_t n_heart_rate;   //heart rate value
int8_t  ch_hr_valid;    //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;


GPIO_InitTypeDef GPIO_InitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RTC_TimeTypeDef   RTC_TimeStructure;
RTC_DateTypeDef   RTC_DateStructure;
EXTI_InitTypeDef EXTI_InitStructure;

//�¼������־��
EventGroupHandle_t g_event_group;

/* ����1-��� */ 
static TaskHandle_t app_task1_handle = NULL;
static TaskHandle_t app_dht11_handle = NULL;
static TaskHandle_t app_rtc_handle = NULL;
static TaskHandle_t app_max30102_handle = NULL;
static TaskHandle_t app_mpu6050_handle = NULL;
static TaskHandle_t app_bel_handle = NULL;
static TaskHandle_t app_esp8266_handle = NULL;
static TaskHandle_t app_mpu6050_step_handle = NULL;

/* ����1-���� */ 
static void app_task1(void* pvParameters);
static void app_dht11(void* pvParameters);
static void app_rtc(void* pvParameters);
static void app_max30102(void* pvParameters);
static void app_mpu6050(void* pvParameters);
static void app_bel(void* pvParameters);
static void app_esp8266(void* pvParameters);
static void app_mpu6050_step(void* pvParameters);

uint32_t g_mpu6050_set = 0;

void tim3_init(void);

// ������
int main(void)
{
	
	
	/* ����ϵͳ�ж����ȼ�����4��Ĭ��FreeRTOS������ */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	/* ϵͳ��ʱ���ж�Ƶ��ΪconfigTICK_RATE_HZ */
	SysTick_Config(SystemCoreClock/configTICK_RATE_HZ);		
	
	uint32_t i=0;
	uint16_t tp_x,tp_y;
	
	// led��ʼ��
	led_init();

	// beep��ʼ��
	beep_init();
		
	
	// key��ʼ��
	key_init();
	
	
	// ����1��ʼ��������Ϊ115200bps
	usart1_init(115200);

	// �����ӳ�һ�ᣬȷ��оƬ�ڲ����ȫ����ʼ��,printf���������
	delay_ms(1000);

	printf("\r\n This is tft test with ST7796S and LVGL by Teacher.Wen\r\n");
	
	// ��ʼ��lvgl
	lv_init();
	
	// ��ʼ��lvgl��ʾ�豸
	lv_port_disp_init();

	// ��ʼ��lvgl�����豸
	lv_port_indev_init();

	//��ʼ��ui
	ui_init();
	
	//��ʼ��dht11;
	dht11_init();
	
	//��ʼ��rtc
	rtc_init();
	
	//��ʼ��max30102
	max30102_init();
	
	//��ʼ��MPU6050	
	MPU_Init();
	
	//��ʼ������
	BLE_Config(9600);
	
	/* esp8266��ʼ�� */
	esp8266_init();
	
	//lv_demo_benchmark();	
	

	// tim3��ʼ������ʱ����Ϊ1ms
	tim3_init();

	/* ����app_task1���� */
	xTaskCreate((TaskFunction_t )app_task1,  		/* ������ں��� */
			  (const char*    )"app_task1",			/* �������� */
			  (uint16_t       )2048,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )4, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_task1_handle);	/* ������ƿ�ָ�� */ 
	
	/* ����app_dth11���� */
	xTaskCreate((TaskFunction_t )app_dht11,  		/* ������ں��� */
			  (const char*    )"app_dht11",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_dht11_handle);	/* ������ƿ�ָ�� */ 
	
	/* ����rtc���� */
	xTaskCreate((TaskFunction_t )app_rtc,  		/* ������ں��� */
			  (const char*    )"app_rtc",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_rtc_handle);	/* ������ƿ�ָ�� */ 
			  
	/* ����max30102���� */
	xTaskCreate((TaskFunction_t )app_max30102,  		/* ������ں��� */
			  (const char*    )"app_max30102",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_max30102_handle);	/* ������ƿ�ָ�� */ 
	
	/* ����mpu6050���� */
	xTaskCreate((TaskFunction_t )app_mpu6050,  		/* ������ں��� */
			  (const char*    )"app_mpu6050",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_mpu6050_handle);	/* ������ƿ�ָ�� */ 
	
	/* ����bel���� */
	xTaskCreate((TaskFunction_t )app_bel,  		/* ������ں��� */
			  (const char*    )"app_bel",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_bel_handle);	/* ������ƿ�ָ�� */ 
	
	/* ����esp8266���� */
	xTaskCreate((TaskFunction_t )app_esp8266,  		/* ������ں��� */
			  (const char*    )"app_esp8266",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_esp8266_handle);	/* ������ƿ�ָ�� */ 
	
	/* ����esp8266���� */
	xTaskCreate((TaskFunction_t )app_mpu6050_step,  		/* ������ں��� */
			  (const char*    )"app_mpu6050_step",			/* �������� */
			  (uint16_t       )512,  				/* ����ջ��С */
			  (void*          )NULL,				/* ������ں������� */
			  (UBaseType_t    )5, 					/* ��������ȼ� */
			  (TaskHandle_t*  )&app_mpu6050_step_handle);	/* ������ƿ�ָ�� */
	
			  
	/* �����¼���־�� */
	g_event_group=xEventGroupCreate();
			  
	/* ����������� */
	vTaskStartScheduler(); 
	while(1);
	

	return 0;
}

static void app_task1(void* pvParameters)
{
	
	int32_t t= 0;
	for(;;)
	{
		
		lv_task_handler();
		delay_ms(1);
		
		t++;
		if(scream_change == 0)
		{
			 if(t == 1000)
			 {
				 
				 /* �����¼����bit0Ϊ1 */
				 xEventGroupSetBits(g_event_group,0x01);
				 t = 0;
			 }
			 if(t == 400)
			 {
			 /* �����¼����bit1Ϊ1 */
				 xEventGroupSetBits(g_event_group,0x02);
			 }	
			if(t == 800)
			{
			   xEventGroupSetBits(g_event_group,0x08);
				
			}
			 
		}
		if(scream_change == 1)
		{
			if(t == 600)
			{
				xEventGroupSetBits(g_event_group,0x04);
				t = 0;
				
			}
		}
		if(BLE_Event)
		{
				xEventGroupSetBits(g_event_group,0x10);
		}
		if(PAin(0)==0)
		{
				xEventGroupSetBits(g_event_group,0x20);
		}
		if(scream_change == 0)
		{
			 xEventGroupSetBits(g_event_group,0x40);
		}
		
	}
}   

static void app_dht11(void *pvParameters)
{
	EventBits_t event_bits;
	uint8_t buf[5];
	int32_t a =1;
	uint8_t str[10];
	int32_t HP;
	while(1)
	{
		event_bits = xEventGroupWaitBits(g_event_group,0x01,pdTRUE,pdFALSE,portMAX_DELAY);
		if(event_bits & 0x01)
		{
			printf("%s\r\n",str);
			a=1;
			memset(str, 0 ,sizeof(str));
			while(a)
			a = dht11_read(buf);

			sprintf(str, "%d.%d ��C", buf[2],buf[3]);
			
			lv_label_set_text(ui_Label10, str);
			
			memset(str, 0 ,sizeof(str));
			sprintf(str,"%d%%",buf[0]);
			lv_label_set_text(ui_Label6, str);
			HP = atoi(str);
			lv_slider_set_value(ui_Slider3,HP,LV_ANIM_OFF);
		}
		
	}
}

static void app_rtc(void *pvParameters)
{
	
	
	EventBits_t event_bits;
	uint8_t str[10];
	while(1)
	{	
		event_bits = xEventGroupWaitBits(g_event_group,0x02,pdTRUE,pdFALSE,portMAX_DELAY);
		if(event_bits & 0x02)
		{
			memset(str, 0 ,sizeof(str));
			RTC_GetTime(RTC_Format_BIN,&RTC_TimeStructure);
			printf("Time %02d:%02d:%02d\r\n",
					RTC_TimeStructure.RTC_Hours,
					RTC_TimeStructure.RTC_Minutes,
					RTC_TimeStructure.RTC_Seconds);
			sprintf(str, "%d:%d", RTC_TimeStructure.RTC_Hours,RTC_TimeStructure.RTC_Minutes);
			lv_label_set_text(ui_Label1, str);
			lv_label_set_text(ui_Label5, str);
			RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);
			memset(str, 0 ,sizeof(str));
			sprintf(str, "%d-%d", RTC_DateStructure.RTC_Month,RTC_DateStructure.RTC_Date);
			lv_label_set_text(ui_Label9, str);
			switch(RTC_DateStructure.RTC_WeekDay)
			{
				case 1:
					lv_label_set_text(ui_Label3, "Mon");
					break;
				case 2:
					lv_label_set_text(ui_Label3, "Tue");
					break;
				case 3:
					lv_label_set_text(ui_Label3, "Wen");
					break;
				case 4:
					lv_label_set_text(ui_Label3, "Thu");
					break;
				case 5:
					lv_label_set_text(ui_Label3, "Fir");
					break;
				case 6:
					lv_label_set_text(ui_Label3, "Sat");
					break;
				case 7:
					lv_label_set_text(ui_Label3, "Sun");
					break;
				default:
					break;
			}
		}
		
	}
	
}

static void app_max30102(void *pvParameters)
{
	int32_t un_heart = 0;

	EventBits_t event_bits;
	
	//variables to calculate the on-board LED brightness that reflects the heartbeats
	uint32_t un_min, un_max, un_prev_data;  
	int32_t i;
	int32_t n_brightness;
	float f_temp;
	
	uint8_t heart[10] = {0};
	uint8_t spO2[10] = {0};
	uint8_t temp[6];
	
	un_min=0x3FFFF;
	un_max=0;
	
	n_ir_buffer_length=500; //buffer length of 100 stores 5 seconds of samples running at 100sps
	//read the first 500 samples, and determine the signal range
    for(i=0;i<n_ir_buffer_length;i++)
    {
        while(MAX30102_INT==1);   //wait until the interrupt pin asserts
        
		max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
		aun_red_buffer[i] =  (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2];    // Combine values to get the actual number
		aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5];   // Combine values to get the actual number
            
        if(un_min>aun_red_buffer[i])
            un_min=aun_red_buffer[i];    //update signal min
        if(un_max<aun_red_buffer[i])
            un_max=aun_red_buffer[i];    //update signal max
    }
	un_prev_data=aun_red_buffer[i];
	//calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)
    maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid); 
	
	while(1)
	{
		event_bits = xEventGroupWaitBits(g_event_group,0x04,pdTRUE,pdFALSE,portMAX_DELAY);
		if(event_bits & 0x04)
		{
			printf("1111111\r\n");
			i=0;
			un_min=0x3FFFF;
			un_max=0;
			n_ir_buffer_length=500;
			
			/* dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the top
			
			   ��ǰ100������ת�����洢���У��������400�������Ƶ�����
			*/
			
			for(i=100;i<500;i++)
			{
				aun_red_buffer[i-100]=aun_red_buffer[i];
				aun_ir_buffer[i-100]=aun_ir_buffer[i];
				
				/* update the signal min and max 
				   �����ź���Сֵ�����ֵ
				*/
				
				if(un_min>aun_red_buffer[i])
					un_min=aun_red_buffer[i];
				
				if(un_max<aun_red_buffer[i])
					un_max=aun_red_buffer[i];
			}
			
			/* take 100 sets of samples before calculating the heart rate 
			
			   �ڼ�������֮ǰ�ɼ�100������
			*/
			
			for(i=400;i<500;i++)
			{
				un_prev_data=aun_red_buffer[i-1];
				
				while(MAX30102_INT==1);
				
				max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
				
				/* ���ֵ�Ի��ʵ������ */
				aun_red_buffer[i] =  ((temp[0]&0x03)<<16) |(temp[1]<<8) | temp[2];   
				aun_ir_buffer[i] =   ((temp[3]&0x03)<<16) |(temp[4]<<8) | temp[5];   
			
				if(aun_red_buffer[i]>un_prev_data)
				{
					f_temp=aun_red_buffer[i]-un_prev_data;
					
					f_temp/=(un_max-un_min);
					
					f_temp*=MAX_BRIGHTNESS;
					
					n_brightness-=(int32_t)f_temp;
					
					if(n_brightness<0)
						n_brightness=0;
				}
				else
				{
					f_temp=un_prev_data-aun_red_buffer[i];
					
					f_temp/=(un_max-un_min);
					
					f_temp*=MAX_BRIGHTNESS;
					
					n_brightness+=(int32_t)f_temp;
					
					if(n_brightness>MAX_BRIGHTNESS)
						n_brightness=MAX_BRIGHTNESS;
				}
			}
		}

		/* �������ʺ�Ѫ�����Ͷ� */
        maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
		
		/* ͨ��UART�������ͼ��������͵��ն˳��� */
		if((ch_hr_valid == 1)&& (n_heart_rate>=0) && (n_heart_rate<=100))
		{
			memset(heart,0,sizeof(heart));
			printf("����=%d\r\n", n_heart_rate);
			sprintf(heart ,"%d",n_heart_rate);
			lv_label_set_text(ui_Label2, heart);
			lv_label_set_text(ui_Label7, heart);
			un_heart = atoi(heart);
			lv_slider_set_value(ui_Slider1,un_heart, LV_ANIM_OFF);
		}

		
		if((ch_spo2_valid ==1)&& (n_sp02>=95) && (n_sp02<=100))
		{
			memset(spO2,0,sizeof(spO2));
			printf("Ѫ��Ũ��=%d\r\n", n_sp02); 
			sprintf(spO2,"%d",n_sp02);
			lv_label_set_text(ui_Label13, spO2);
			
		}			
	
		//delay_ms(100);
		printf("1111111\r\n");
	}

}

static void app_mpu6050(void *pvParameters)
{
	unsigned long  step_count_last=0;
	unsigned long  step_count=0;
	uint32_t sedentary_event=0;
	uint32_t t=0;
	EventBits_t event_bits;
	char *str = NULL;
	
	while(mpu_dmp_init())
	{
		printf("[ERROR] MPU6050 ERROR \r\n");
		delay_ms(500);
	}
	
	while(dmp_set_pedometer_step_count(0))
	{
		delay_ms(500);
	}
	
	while(1)
	{
			event_bits = xEventGroupWaitBits(g_event_group,0x08,pdTRUE,pdFALSE,portMAX_DELAY);
			if(event_bits & 0x08)
			/* ��ȡ���� */
			dmp_get_pedometer_step_count(&step_count);
			
			/* ��鲽���ı仯 */
			if((step_count - step_count_last) < 5)
			{
				/* �����仯���������þ����¼���־λΪ1 */
				sedentary_event=1;
			}
			
//			printf("[INFO] ��ǰ����:%ld ��ǰ����:%ld\r\n",step_count,step_count_last);
			
			step_count_last=step_count;
			sprintf(str,"%d",step_count_last);
			lv_label_set_text(ui_Label12, str);
			lv_slider_set_value(ui_Slider2,step_count_last, LV_ANIM_OFF);
			
			t=0;
		

		
		if(sedentary_event)
		{
			sedentary_event=0;
			
//			printf("[INFO] �������ã���վ��������...\r\n");
			

		}
		
		/* ��ʱһ�� */
		delay_ms(100);
	}
	
}

static void app_bel(void *pvParameters)
{
	int32_t hours = 0;
	int32_t minutes = 0;
	int32_t seconds = 0;
	char* src1 = NULL;
	char* src2 = NULL;
	
	EventBits_t event_bits;
	while(1)
	{
		event_bits = xEventGroupWaitBits(g_event_group,0x10,pdTRUE,pdFALSE,portMAX_DELAY);
		if(event_bits & 0x10)
		{
			printf("111111\r\n");
			printf("%s\r\n",BLE_Buf);
			if(strncmp((const char*)BLE_Buf,"time",4) == 0)
			{
				src1 = strchr((const char *)BLE_Buf,'-');
				if(src1 != NULL)
				{
					src1++;
					printf("%s\r\n",src1);
					hours =  atoi(src1);
					printf("%d\r\n",hours);
				}
				src2 = strchr(src1,'-');
				if(src2 != NULL)
				{
					src2++;
					printf("%s\r\n",src2);
					minutes = atoi(src2);
					printf("%d\r\n",minutes);
					
				}
				RTC_TimeStructure.RTC_Hours   = hours;
				RTC_TimeStructure.RTC_Minutes = minutes;
				RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure);
			}
		}
		BLE_Event = 0;
		BLE_Cnt = 0;
		memset(BLE_Buf,0,sizeof(BLE_Buf));
	}
	
	
	
}

static void app_esp8266(void* pvParameters)
{
	int32_t rt;
	
	uint8_t buf[64];
	EventBits_t event_bits;
	
	
	while(1)
	{
		event_bits = xEventGroupWaitBits(g_event_group,0x20,pdTRUE,pdFALSE,portMAX_DELAY);
		if(event_bits & 0x20)
		{
			printf("111111\r\n");
			NVIC_DisableIRQ(RTC_WKUP_IRQn);
			rt = net_init(AP_SSID,AP_PASS);
			if(rt == 0)
			{
				/* D1�Ƶ�����ʾ�����ȵ�ɹ� */
				PFout(9)=0;
			}
			else
			{
				/* D1�����ʾ�����ȵ�ʧ�� */		
				PFout(9)=1;
			}	

			NVIC_EnableIRQ(RTC_WKUP_IRQn);	
			
			NVIC_DisableIRQ(RTC_WKUP_IRQn);
					
			/* ���ӷ����� */
			rt = net_connect_server();
			
			if(rt == 0)
			{
				printf("[OK] net connect time server success\r\n");
				
				/* D2�Ƶ�����ʾ���ӷ������ɹ� */
				PFout(10)=0;
			}
			else
			{
				printf("[error] net connect time server fail\r\n");
				
				/* D2�Ƶ�����ʾ���ӷ�����ʧ�� */
				PFout(10)=1;
			}	

			NVIC_EnableIRQ(RTC_WKUP_IRQn);
			NVIC_DisableIRQ(RTC_WKUP_IRQn);
			
			memset(buf,0,sizeof buf);
			
			
			rt=net_get_time(buf);	

			if(rt == 0)
			{
				printf("[OK] net date:%s",buf);//Date: Sat, 27 Nov 2021 16:09:55 GMT
				
				rt = net_time_to_rtc((const char *)buf);
				
				if(rt == 0)
				{
//					PFout(8)=1;
//					delay_ms(100);
//					PFout(8)=0;				
				
				}

				
			}
			else
			{
				printf("[error] net get time fail\r\n");
			}
			
		
			NVIC_EnableIRQ(RTC_WKUP_IRQn);

			NVIC_DisableIRQ(RTC_WKUP_IRQn);
			
			//��ȡʱ��
			RTC_GetTime(RTC_Format_BCD,&RTC_TimeStructure);
			printf("Time %02x:%02x:%02x\r\n",RTC_TimeStructure.RTC_Hours,RTC_TimeStructure.RTC_Minutes,RTC_TimeStructure.RTC_Seconds);

			//��ȡ����
			RTC_GetDate(RTC_Format_BCD,&RTC_DateStructure);
			printf("Date 20%02x/%02x/%02x Week:%x\r\n",RTC_DateStructure.RTC_Year,RTC_DateStructure.RTC_Month,RTC_DateStructure.RTC_Date,RTC_DateStructure.RTC_WeekDay);
					
			
			
			NVIC_EnableIRQ(RTC_WKUP_IRQn);
			
			NVIC_DisableIRQ(RTC_WKUP_IRQn);
			
			rt = net_disconnect_server();
			
			if(rt == 0)
			{
				printf("[OK] net disconnect server success\r\n");
				
				PFout(10)=1;
			}
			else
			{
				printf("[error] net disconnect server fail\r\n");
			}

			
			rt =esp8266_disconnect_ap();
			
			if(rt == 0)
			{
				printf("[OK] net disconnect ap success\r\n");
				
				PFout(9)=1;
			}
			else
			{
				printf("[error] net disconnect ap fail\r\n");
			}

			NVIC_EnableIRQ(RTC_WKUP_IRQn);
		
		}
	}
}


static void app_mpu6050_step(void *pvParameters)
{
	float pitch,roll,yaw; 		//ŷ����
	EventBits_t event_bits;
	
	uint8_t res;
	while(1)
	{
		event_bits = xEventGroupWaitBits(g_event_group,0x40,pdTRUE,pdFALSE,portMAX_DELAY);
		if(event_bits & 0x40)
		{
			res = mpu_dmp_get_data(&pitch,&roll,&yaw);
			
			if(res == 0)
			{
				
				
				if(roll<5)
				{
					
					_ui_screen_change(&ui_Screen1, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen1_screen_init);
					scream_change == 1;
				}
				if(roll>5)
				{
					
					
					_ui_screen_change(&ui_Screen2, LV_SCR_LOAD_ANIM_FADE_ON, 500, 0, &ui_Screen2_screen_init);
					
				}
			}
		}
	
	}
	
	
}

/*-----------------------------------------------------------*/

void vApplicationMallocFailedHook( void )
{
	/* vApplicationMallocFailedHook() will only be called if
	configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
	function that will get called if a call to pvPortMalloc() fails.
	pvPortMalloc() is called internally by the kernel whenever a task, queue,
	timer or semaphore is created.  It is also called by various parts of the
	demo application.  If heap_1.c or heap_2.c are used, then the size of the
	heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
	FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
	to query the size of free heap space that remains (although it does not
	provide information on how the remaining heap might be fragmented). */
	taskDISABLE_INTERRUPTS();
	for( ;; );
}
/*-----------------------------------------------------------*/

void vApplicationIdleHook( void )
{
	/* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
	to 1 in FreeRTOSConfig.h.  It will be called on each iteration of the idle
	task.  It is essential that code added to this hook function never attempts
	to block in any way (for example, call xQueueReceive() with a block time
	specified, or call vTaskDelay()).  If the application makes use of the
	vTaskDelete() API function (as this demo application does) then it is also
	important that vApplicationIdleHook() is permitted to return to its calling
	function, because it is the responsibility of the idle task to clean up
	memory allocated by the kernel to any task that has since been deleted. */
}
/*-----------------------------------------------------------*/

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
	( void ) pcTaskName;
	( void ) pxTask;
	printf("%s",pcTaskName);
	/* Run time stack overflow checking is performed if
	configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
	function is called if a stack overflow is detected. */
	taskDISABLE_INTERRUPTS();
	for( ;; );
}


void vApplicationTickHook( void )
{

}
